#include "programControl.h"
#define VNAME(value) (#value)

int ProgramControl::createPosNum()
{
    int index;
    for(int i = 1;;i++)
    {
        if(isPosNumInWids(i,&index,NULL) == false)return i;
    }
}

void ProgramControl::createPos(mat pos)
{
    int num = createPosNum();
    DemonstrateWidget* wid = new DemonstrateWidget(NULL,num,pos);
    connect(wid,SIGNAL(windowClicked(DemonstrateWidget*)),this,SLOT(on_demonstrate_clicked(DemonstrateWidget*)));
    connect(wid,SIGNAL(numChanged(DemonstrateWidget*,int)),this,SLOT(on_demonstrate_num_changed(DemonstrateWidget*,int)));
    lay->addWidget(wid);
    pWidList.push_back(wid);
    qDebug()<<"widget count:"<<pWidList.size();
}

void ProgramControl::createPos(DemonstrateWidget* wid)
{
    if(wid == NULL){
        qDebug()<<"widget is NULL!";
        return;
    }
    connect(wid,SIGNAL(windowClicked(DemonstrateWidget*)),this,SLOT(on_demonstrate_clicked(DemonstrateWidget*)));
    connect(wid,SIGNAL(numChanged(DemonstrateWidget*,int)),this,SLOT(on_demonstrate_num_changed(DemonstrateWidget*,int)));
    lay->addWidget(wid);
    pWidList.push_back(wid);
    //qDebug()<<"widget count:"<<pWidList.size();
}

void ProgramControl::deletePos()
{
    list<DemonstrateWidget*>::iterator it;
    if(selectedDemoWid == NULL)return;
    for(it = pWidList.begin();it != pWidList.end();it++)
    {
        if((*it) == selectedDemoWid)
        {
            break;
        }
    }
    pWidList.remove(selectedDemoWid);
    delete selectedDemoWid;
    selectedDemoWid = NULL;
}

list<mat> ProgramControl::getSectionPosList()
{
    list<mat> pos;
    list<DemonstrateWidget*>::iterator it;
    bool biggerSelected = false;
    while(it != pWidList.end())
    {
        if((*it) == selectedDemoWid)biggerSelected = true;
        if(biggerSelected)pos.push_back((*it)->getPos());
        it++;
    }
    return pos;
}

list<mat> ProgramControl::getAllPosList()
{
    list<mat> pos;
    list<DemonstrateWidget*>::iterator it;
    while(it != pWidList.end())
    {
        pos.push_back((*it)->getPos());
        it++;
    }
    return pos;
}

bool ProgramControl::isPosNumInWids(int num,int* index,DemonstrateWidget* wid)
{
    list<DemonstrateWidget*>::iterator it;
    (*index) = 0;
    for(it = pWidList.begin();it != pWidList.end();it++)
    {
        if((*it)->getNum() == num && wid != (*it))return true;
        (*index)++;
    }
    return false;
}


void ProgramControl::on_demonstrate_clicked(DemonstrateWidget* wid)
{
    selectedDemoWid = wid;
}

void ProgramControl::on_demonstrate_num_changed(DemonstrateWidget* wid,int num)
{
    int index;
    if(isPosNumInWids(num,&index,wid))
    {
        list<DemonstrateWidget*>::iterator it = pWidList.begin();
        while(index--)it++;
        wid->setPos((*it)->getPos());
    }
}

void ProgramControl::createProgramFile(string path)
{

    cJSON* jsn = cJSON_CreateObject();
    if(pWidList.size()==0){
        qDebug()<<VNAME(pWidList)<<"don't has element!";
        return;
    }
    int index = 0;
    for (list<DemonstrateWidget*>::iterator it = pWidList.begin();\
         it != pWidList.end(); it++) {
       cout<<cJSON_Print((*it)->getJsonInfo())<<endl;
//       string posNum = "P[" + to_string((*it)->getNum()) + "]";
       string indexName = "Index_" + to_string(index);
       cJSON_AddItemToObject(jsn,indexName.c_str(),(*it)->getJsonInfo());
       index++;
    }
    cout<<cJSON_Print(jsn);
    fstream file(path,ios::out);
    if(!file.is_open()){
        qDebug()<<"file open filed";
    }
    file<<cJSON_PrintUnformatted(jsn)<<endl;
    file.close();
    qDebug()<<"successfully save the program!";
}

ProgramControl::~ProgramControl()
{
    for(list<DemonstrateWidget*>::iterator it = pWidList.begin();\
        it != pWidList.end();it++){
        delete (*it);
        qDebug()<<"delete:"<<VNAME(*it);
    }
}

void ProgramControl::loadProgramFile(string path)
{
    fstream file(path,ios::in|ios::out);
    if(!file.is_open()){
        qDebug()<<VNAME(file)<<"open filed";
        return;
    }
    qDebug()<<"Open "<<QString(path.c_str())<<" successfully!";
    string str;
    file>>str;
    qDebug()<<"File info was written to string";
    cJSON* root = cJSON_Parse(str.c_str());
    if(root == NULL){
        qDebug()<<"Parse failed!";
        file.close();
        return;
    }
    cJSON* obj_temp = NULL;
    const string prefix = "Index_";
    string strIndex;
    int i = 0;
    list<DemonstrateWidget*> tempctrl;
    while(true)
    {
        strIndex = prefix + to_string(i);
        obj_temp = cJSON_GetObjectItem(root,strIndex.c_str());
        if(obj_temp == NULL){
            qDebug()<<"Already get all the pos";
            file.close();
            break;
        }
        DemoMsg temp;
        DemonstrateWidget::setJsonInfo(obj_temp,&temp);
        DemonstrateWidget* wid = new DemonstrateWidget(NULL,temp);
        tempctrl.push_back(wid);
        i++;
    }
    qDebug()<<"Delete the current widget";
    // free all the widget
    qDebug()<<"pWidList.size"<<pWidList.size();
    for(list<DemonstrateWidget*>::iterator it = pWidList.begin();\
        it != pWidList.end();it++){
        qDebug()<<(*it);
        delete (*it);
    }
    pWidList.clear();
    for(list<DemonstrateWidget*>::iterator it = tempctrl.begin();\
        it != tempctrl.end();it++){
        qDebug()<<(*it);
        createPos(*it);
    }
    qDebug()<<"number of pWidList"<<pWidList.size();
}

